﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading;

namespace WindSim
{
    [ServiceContract(Name = "SimulationService", CallbackContract = typeof(ISimulationServiceCallback), SessionMode = SessionMode.Required)]
    public interface ISimulationService
    {
        //Register / Unregister
        #region ...
        [OperationContract(IsOneWay = true)]
        void RegisterClient(Guid Id, ClientType type, ModelData modelData);

        [OperationContract(IsOneWay = true)]
        void UnRegisterClient(Guid Id, ClientType type);
        #endregion

        //Called from Controller
        #region ...
        [OperationContract(IsOneWay = true)]
        void SetPowerStateAtModel(Guid Id, PowerState State);

        [OperationContract(IsOneWay = true)]
        void SetFunctionStateAtModel(Guid Id, FunctionState State);

        [OperationContract(IsOneWay = true)]
        void SetWindDirectionAtModel(Guid Id, double DirectionAngle);

        [OperationContract(IsOneWay = true)]
        void SetWindSpeedAtModel(Guid Id, double Speed);

        [OperationContract(IsOneWay = true)]
        void SetDayTimeAtModel(Guid Id, DateTime Time);

        [OperationContract(IsOneWay = true)]
        void SetControlTypeAtModel(Guid Id, SimControlType ControlType);
        #endregion

        //Called from Model
        #region ...
        [OperationContract(IsOneWay = true)]
        void SendPowerStateToController(Guid Id, PowerState State);

        [OperationContract(IsOneWay = true)]
        void SendFunctionStateToController(Guid Id, FunctionState State);

        [OperationContract(IsOneWay = true)]
        void SendRPMToController(Guid Id, double RPM);

        [OperationContract(IsOneWay = true)]
        void SendEnergyToController(Guid Id, double Energy);

        [OperationContract(IsOneWay = true)]
        void SendNameToController(Guid Id, string Name);

        [OperationContract(IsOneWay = true)]
        void SendLocationToController(Guid Id, string Location);
        #endregion
    }

    public interface ISimulationServiceCallback
    {
        //Register / Unregister
        #region ...
        [OperationContract(IsOneWay = true)]
        void NotifyControllerModelRegistered(Guid Id, ModelData modelData);

        [OperationContract(IsOneWay = true)]
        void NotifyControllerModelUnregistered(Guid Id);
        #endregion

        //Used to notify Controller
        #region ...
        [OperationContract(IsOneWay = true)]
        void NotifyControllerPowerStateChanged(Guid Id, PowerState State);

        [OperationContract(IsOneWay = true)]
        void NotifyControllerFunctionStateChanged(Guid Id, FunctionState State);

        [OperationContract(IsOneWay = true)]
        void NotifyControllerRPMChanged(Guid Id, double RPM);

        [OperationContract(IsOneWay = true)]
        void NotifyControllerEnergyChanged(Guid Id, double Energy);

        [OperationContract(IsOneWay = true)]
        void NotifyControllerNameChanged(Guid Id, string Name);

        [OperationContract(IsOneWay = true)]
        void NotifyControllerLocationChanged(Guid Id, string Location);
        #endregion

        //Used to notify Model
        #region ...
        [OperationContract(IsOneWay = true)]
        void NotifyModelPowerStateChanged(PowerState State);

        [OperationContract(IsOneWay = true)]
        void NotifyModelFunctionStateChanged(FunctionState State);

        [OperationContract(IsOneWay = true)]
        void NotifyModelWindDirectionChanged(double DirectionAngle);

        [OperationContract(IsOneWay = true)]
        void NotifyModelWindSpeedChanged(double Speed);

        [OperationContract(IsOneWay = true)]
        void NotifyModelDayTimeChanged(DateTime Time);

        [OperationContract(IsOneWay = true)]
        void NotifyModelControlTypeChanged(SimControlType ControlType);
        #endregion
    }

    [DataContract(Name = "Client")]
    public class Client
    {
        [DataMember]
        public Guid Id { get; set; }
        [DataMember]
        public ClientType Type { get; set; }
    }

    [DataContract(Name = "ModelData")]
    public class ModelData
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Location { get; set; }
        [DataMember]
        public double RPM { get; set; }
        [DataMember]
        public double Energy { get; set; }
        [DataMember]
        public PowerState PowerstateController { get; set; }
        [DataMember]
        public PowerState PowerstateModel { get; set; }
        [DataMember]
        public FunctionState FunctionstateModel { get; set; }
        [DataMember]
        public double WindSpeed { get; set; }
        [DataMember]
        public double WindDirection { get; set; }
        [DataMember]
        public DateTime DayTime { get; set; }
        [DataMember]
        public SimControlType ControlType { get; set; }
    }

    [DataContract]
    public enum ClientType
    {
        [EnumMember]
        Model,
        [EnumMember]
        Controller
    }

    [DataContract]
    public enum FunctionState
    {
        [EnumMember]
        OK,
        [EnumMember]
        Error
    }

    [DataContract]
    public enum PowerState
    {
        [EnumMember]
        On,
        [EnumMember]
        Off
    }

    [DataContract]
    public enum SimControlType
    {
        [EnumMember]
        Manual,
        [EnumMember]
        Automatic1,
        [EnumMember]
        Automatic2,
    }
}
